package com.zhanglijie.base.other.waitAndNotify;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

import org.openjdk.jmh.annotations.Threads;

/**
 * @author zhanglijie
 * @version 1.0
 * @since 1.1.0 2022/6/19 0019 21:23
 *  打印不够400个线程？是因为主线程执行完嘛？不是，开启的生产者和消费者不是守护线程
 *  这是因为虚假唤醒的原因 唤醒之后不会打印生产和消费
 *  解决不是threads[i]=thread,threads[i].join操作
 *  而是while(true） break;
 */
public class ManyProAndConsume {
    private final static Object OBJECT = new Object();
    private static volatile int COUNT = 0;
    private static final int MAX = 10;
    public static void main(String[] args) throws InterruptedException {
        ManyProAndConsume manyProAndConsume = new ManyProAndConsume();
        int size = 200;
        for (int i = 0; i < size; i++) {
            Thread pro = new Thread(() -> {
                synchronized (OBJECT) {
                    while(true) {
                        if (COUNT < MAX) {
                            manyProAndConsume.produce();
                            OBJECT.notifyAll();
                            break;
                        } else {
                            try {
                                OBJECT.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            },"produce"+i);

            Thread consume = new Thread(() -> {
                  synchronized (OBJECT) {
                      while (true) {
                          if (COUNT > 0) {
                              manyProAndConsume.consume();
                              OBJECT.notifyAll();
                              break;
                          } else {
                              try {
                                  OBJECT.wait();
                              } catch (InterruptedException e) {
                                  e.printStackTrace();
                              }
                          }
                      }
                  }
            },"consumer"+i);
            pro.start();
            consume.start();
        }

    }
    public void produce(){
        System.out.println(Thread.currentThread().getName()+"====produce====="+(++COUNT));
    }

    public void consume(){
        System.out.println(Thread.currentThread().getName()+"======consume======"+(COUNT--));
    }
}
